package top.buluoluo.ordersservice.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import top.buluoluo.commoncore.domain.response.Result;
import top.buluoluo.ordersservice.client.ProductServiceClient;
import top.buluoluo.ordersservice.dto.request.OrderAddRequest;
import top.buluoluo.ordersservice.dto.request.OrderPageRequest;
import top.buluoluo.ordersservice.dto.request.OrderPayRequest;
import top.buluoluo.ordersservice.dto.respone.*;
import top.buluoluo.ordersservice.dto.result.PageResult;
import top.buluoluo.ordersservice.entity.OrderItems;
import top.buluoluo.ordersservice.entity.Orders;
import top.buluoluo.ordersservice.enums.OrderStatus;
import top.buluoluo.ordersservice.mapper.OrderItemsMapper;
import top.buluoluo.ordersservice.mapper.OrderMapper;
import top.buluoluo.ordersservice.service.OrderService;
import org.springframework.data.redis.core.RedisTemplate;
import top.buluoluo.ordersservice.utils.OrderCacheKeyUtil;
import top.buluoluo.ordersservice.utils.OrderNoGenerator;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
@Slf4j
public class OrderServiceImpl implements OrderService {
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private OrderItemsMapper orderItemsMapper;
    @Autowired
    private ProductServiceClient productServiceClient;

    @Override
    public Result<OrderDTO> getOrderById(String orderId) {
        try {
            if (orderId == null)
                return Result.failed("请求订单id为空");
            Long orderIdLong=Long.parseLong(orderId);
            LambdaQueryWrapper<OrderItems> orderItemsQueryWrapper = new LambdaQueryWrapper<>();
            orderItemsQueryWrapper.eq(OrderItems::getOrderId, orderIdLong);
            OrderItems orderItems = orderItemsMapper.selectOne(orderItemsQueryWrapper);
            OrderDTO orderDTO = OrderDTO.fromEntity(orderMapper.selectById(orderIdLong),orderItems);
            return Result.success(orderDTO);
        } catch (Exception e) {
            return Result.failed("服务器异常"+e);
        }
    }

    @Override
    public Result<PageResult<OrderDTO>> getOrderByUserId(OrderPageRequest request) {
        // 构建缓存键（包含用户ID和分页参数）
//        String cacheKey = String.format("orders:user:%d:page:%d:size:%d",
//                request.getUserId(), request.getPageNum(), request.getPageSize());
        String cacheKey = OrderCacheKeyUtil.getUserOrderPageKey(
                request.getUserId(),
                request.getPageNum(),
                request.getPageSize()
        );
        // 尝试从缓存获取
        Object cachedObject = redisTemplate.opsForValue().get(cacheKey);
        if (cachedObject != null) {
            try {
                PageResult<OrderDTO> cachedResult = (PageResult<OrderDTO>) cachedObject;
                log.info("从缓存中获取订单分页信息：{}", cachedResult);
                return Result.success(cachedResult);
            } catch (ClassCastException e) {
                log.warn("缓存数据格式不匹配，将从数据库重新获取", e);
                // 继续从数据库获取
            }
        }

        // 查询订单主表（分页）
        LambdaQueryWrapper<Orders> queryOrderWrapper = new LambdaQueryWrapper<>();
        queryOrderWrapper.eq(Orders::getUserId, request.getUserId());
        if (!Objects.equals(request.getStatus(), "ALL"))
            queryOrderWrapper.eq(Orders::getStatus, request.getStatus());
        Page<Orders> page = new Page<>(request.getPageNum(), request.getPageSize());
        Page<Orders> ordersPage = orderMapper.selectPage(page, queryOrderWrapper);
        if (ordersPage == null || ordersPage.getRecords().isEmpty()) {
            return Result.success(null);
        }
        // 获取订单ID列表
        List<Long> orderIds = ordersPage.getRecords().stream()
                .map(Orders::getId)
                .collect(Collectors.toList());

        // 批量查询订单项
        LambdaQueryWrapper<OrderItems> queryItemsWrapper = new LambdaQueryWrapper<>();
        queryItemsWrapper.in(OrderItems::getOrderId, orderIds);
        List<OrderItems> orderItemsList = orderItemsMapper.selectList(queryItemsWrapper);

        // 构建订单ID到订单项的映射
        Map<Long, OrderItems> orderItemsMap = orderItemsList.stream()
                .collect(Collectors.toMap(OrderItems::getOrderId, item -> item));

        // 组合订单和订单项为DTO
        List<OrderDTO> orderDTOs = ordersPage.getRecords().stream()
                .map(order -> {
                    OrderItems items = orderItemsMap.get(order.getId());
                    if (items == null) {
                        log.warn("订单 {} 未找到对应的订单项", order.getId());
                        return null;
                    }
                    return OrderDTO.fromEntity(order, items);
                })
                .filter(Objects::nonNull)
                .collect(Collectors.toList());

        // 构建分页结果
        PageResult<OrderDTO> pageResult = new PageResult<>(request.getPageNum(), request.getPageSize(), (int) ordersPage.getTotal(), orderDTOs);

        // 存入缓存
//        redisTemplate.opsForValue().set(cacheKey, pageResult, 30, TimeUnit.MINUTES);

        return Result.success(pageResult);
    }

    @Override
    public Result<OrderAddDTO> addOrder(OrderAddRequest request) {
//        这里只实现了一个订单包含一各种类商品的功能，我很想实现一个订单包含多种商品，但时间真的不够了，我必须快速基本完成这个项目然后写简历，实属可惜。
            try {
                if (request == null)
                    return Result.failed("请求参数错误");
                Orders orders = request.toOrders();
                String orderNo = OrderNoGenerator.generate();
                orders.setOrderNo(orderNo);
                orderMapper.insert(orders);
                OrderItems orderItems = request.toOrderItems();
                orderItems.setOrderId(orders.getId());
                try{
                    Result<SkuDTO> skuDTOResult= productServiceClient.getSkuBySpuId(orderItems.getSkuId());
                    orderItems.setImageUrl(skuDTOResult.getData().getImageUrl());
                    orderItems.setSkuSpecs(skuDTOResult.getData().getSpecs());
                    orderItems.setUnitPrice(skuDTOResult.getData().getOriginalPrice());
                    Result<SpuDTO> spuDTOResult = productServiceClient.getSpuBySpuId(orderItems.getProductId());
                    orderItems.setProductName(spuDTOResult.getData().getName());
                    orderItemsMapper.insert(orderItems);
                    OrderAddDTO orderAddDTO = new OrderAddDTO(String.valueOf(orders.getId()) ,true);
                    clearUserOrderCache(orders.getId());
                    return Result.success(orderAddDTO);
                }catch (Exception e){
                    log.error("获取商品信息失败:",e);
                }
                return Result.failed("添加订单失败");
            } catch (Exception e) {
                return Result.failed(e.getMessage());
            }
    }
/**
 * 支付订单
 */
    @Override
    public Result<OrderPayDTO> payOrder(OrderPayRequest request) {
        try {
            if (request == null)
                return Result.failed("请求参数错误");
            Orders orders = new Orders();
            orders.setId(request.getOrderId());
            orders.setPaymentMethod(request.getPayMethod());
            orders.setPaymentTime(request.getPayTime());
            orders.setStatus(OrderStatus.PAID);
            orderMapper.updateById(orders);
            OrderPayDTO orderPayDTO = OrderPayDTO.fromEntity(orderMapper.selectById(orders.getId()));
            clearUserOrderCache(orderPayDTO.getUserId());
            return Result.success(orderPayDTO);
        } catch (Exception e) {
            return Result.failed(e.getMessage());
        }
    }
    /**
     * 清除用户所有订单分页缓存
     * @param userId 用户ID
     */
    private void clearUserOrderCache(Long userId) {
        // 获取所有匹配的缓存键
        String pattern = OrderCacheKeyUtil.getUserOrderPrefix(userId);
        Set<String> keys = redisTemplate.keys(pattern);

        if (!keys.isEmpty()) {
            log.info("清除用户 {} 的订单缓存: {} 个键", userId, keys.size());
            redisTemplate.delete(keys);
        }
    }
}
